﻿using Abp.Application.Services.Dto;
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.Organizations;
using Abp.Runtime.Session;
using Abp.UI;
using Camc.Quality.Authorization.Roles;
using Camc.Quality.Authorization.Users;
using Camc.Quality.Authorization.Users.Dto;
using Camc.Quality.Common;
using Camc.Quality.Inspection.InspectionManage;
using Camc.Quality.Inspection.InspectionStrat;
using Camc.Quality.IOperationHistory;
using Camc.Quality.Quality;
using Camc.Quality.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Camc.Quality.Inspection
{
    public class InspectionHandleAppService : QualityAppServiceBase
    {
        private readonly IRepository<InspectionSeverityDesc, Guid> _inspectionSeverityDescRepository;
        private readonly IRepository<InspectionTypeDesc, Guid> _inspectionTypeDescRepository;
        private readonly IRepository<InspectionItemInfo, Guid> _inspectionItemInfoRepository;
        private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
        private readonly IRepository<InspectionStandardDesc, Guid> _inspectionStandardDescRepository;
        private readonly RoleManager _roleManager;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<UserRole, long> _userRoleRepository;
        private readonly IOperationHistoryAppService _iOperationHistoryAppService;
        private readonly IRepository<UploadPicture, Guid> _uploadPictureRepository;
        private readonly IAbpSession _abpSession;
        private readonly ITempFileCacheManager _tempFileCacheManager;

        public InspectionHandleAppService(IRepository<InspectionSeverityDesc, Guid> inspectionSeverityDescRepository,
                             IRepository<InspectionTypeDesc, Guid> inspectionTypeDescRepository,
                             IRepository<InspectionItemInfo, Guid> inspectionItemInfoRepository,
                             IRepository<OrganizationUnit, long> organizationUnitRepository,
                             RoleManager roleManager,
                             IRepository<InspectionStandardDesc, Guid> inspectionStandardDescRepository,
                             IRepository<User, long> userRepository,
                             IRepository<UserRole, long> UserRoleRepository,
                             IOperationHistoryAppService iOperationHistoryAppService,
                             IRepository<UploadPicture, Guid> uploadPictureRepository,
                             IAbpSession abpSession,
                             ITempFileCacheManager tempFileCacheManager
                                    )
        {
            _inspectionSeverityDescRepository = inspectionSeverityDescRepository;
            _inspectionTypeDescRepository = inspectionTypeDescRepository;
            _inspectionItemInfoRepository = inspectionItemInfoRepository;
            _organizationUnitRepository = organizationUnitRepository;
            _roleManager = roleManager;
            _inspectionStandardDescRepository = inspectionStandardDescRepository;
            _userRepository = userRepository;
            _userRoleRepository = UserRoleRepository;
            _iOperationHistoryAppService = iOperationHistoryAppService;
            _uploadPictureRepository = uploadPictureRepository;
            _abpSession = abpSession;
            _tempFileCacheManager = tempFileCacheManager;
        }
        /// <summary>
        /// 任务编号下拉菜单
        /// </summary>
        /// <param name="taskCodeStr"></param>
        /// <returns></returns>
        public List<string> GetCodeTaskList(string taskCodeStr)
        {
            if (string.IsNullOrEmpty(taskCodeStr))
            {
                return _inspectionStandardDescRepository.GetAll().Select(p => p.TaskCode).Distinct().Where(d => d != null).ToList();
            }
            else
            {
                return _inspectionStandardDescRepository.GetAll().Where(p => p.TaskCode.Contains(taskCodeStr)).Select(p => p.TaskCode).Distinct().Where(d => d != null).ToList();
            }
        }
        /// <summary>
        /// 一级异常下拉列表
        /// </summary>
        /// <returns></returns>
        public List<InspectionTypeDescDto> GetInspectionTypeDescList(string typeNameStr)
        {
            var inspectionTypeDesc = _inspectionTypeDescRepository.GetAll().Where(d => d != null && d.IsUsed == InspectionTypeDesc.IsUseds.启用).ToList();

            if (!string.IsNullOrEmpty(typeNameStr))
            {
                inspectionTypeDesc = inspectionTypeDesc.Where(d => d.TypeName.Contains(typeNameStr)).Distinct().ToList();
            }
            var Result = ObjectMapper.Map<List<InspectionTypeDescDto>>(inspectionTypeDesc);
            return Result;
        }
        /// <summary>
        /// 二级异常下拉列表
        /// </summary>
        /// <param name="inspectionTypeDescId"></param>
        /// <returns></returns>
        public List<InspectionItemInfoOutDto> GetInspectionItemInfoList(Guid inspectionTypeDescId, string itemNameStr)
        {
            var inspectionItemInfo = _inspectionItemInfoRepository.GetAll().Where(d => d != null && d.IsUsed == InspectionItemInfo.IsUseds.启用);
            if (inspectionTypeDescId != Guid.Empty)
            {
                inspectionItemInfo = inspectionItemInfo.Where(d => d.TypeId == inspectionTypeDescId);
            }
            if (!string.IsNullOrEmpty(itemNameStr))
            {
                inspectionItemInfo = inspectionItemInfo.Where(d => d.ItemName.Contains(itemNameStr));
            }
            var Result = ObjectMapper.Map<List<InspectionItemInfoOutDto>>(inspectionItemInfo);
            return Result;
        }
        /// <summary>
        /// 异常严重程度下拉列表
        /// </summary>
        /// <returns></returns>
        public List<InspectionSeverityDescOutDto> GetInspectionSeverityDescList(string severityNameStr)
        {
            var severityDesc = _inspectionSeverityDescRepository.GetAll().Where(d => d != null && d.IsUsed == InspectionSeverityDesc.IsUseds.启用).ToList();

            if (!string.IsNullOrEmpty(severityNameStr))
            {
                severityDesc = severityDesc.Where(d => d.SeverityName.Contains(severityNameStr)).Distinct().ToList();
            }
            var Result = ObjectMapper.Map<List<InspectionSeverityDescOutDto>>(severityDesc);
            return Result;
        }
        /// <summary>
        /// 提报人下拉列表
        /// </summary>
        /// <returns></returns>
        public List<UserListDto> GetCreateUserList()
        {
            var query = _inspectionStandardDescRepository.GetAll().ToList();
            if (query.Count() > 0)
            {
                var userList = query.Select(s => s.CreatorUserId).Distinct();
                var queryData = from userid in userList
                                join user in _userRepository.GetAll()
                                on userid equals user.Id
                                select new UserListDto
                                {
                                    Id = (long)userid,
                                    Name = user.Surname + user.Name
                                };
                return queryData.ToList();
            }
            return null;
        }
        /// <summary>
        /// 提报人/处理人下拉列表
        /// </summary>
        /// <param name="inspectionItemInfoId"></param>
        /// <returns></returns>
        public List<UserListDto> GetUserList(Guid inspectionItemInfoId, string userNameStr)
        {
            var userList = _userRepository.GetAll();
            if (inspectionItemInfoId != Guid.Empty)
            {
                var roleId = _inspectionItemInfoRepository.FirstOrDefault(d => d.Id == inspectionItemInfoId).RolesId;
                var queryData = from ul in userList
                                join ur in _userRoleRepository.GetAll()
                                on ul.Id equals ur.UserId
                                where ur.RoleId == roleId
                                select new UserListDto
                                {
                                    Id = ul.Id,
                                    Name = ul.Surname + ul.Name
                                };

                if (!string.IsNullOrEmpty(userNameStr))
                {
                    queryData = queryData.Where(d => d.Name.Contains(userNameStr)).Distinct();
                }
                var result = ObjectMapper.Map<List<UserListDto>>(queryData.ToList());
                return result;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 异常管理表修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResultMessage> UpdateInspectionStandardDesc(InspectionStandardDescDto input)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                var userId = GetCurrentUser().Id; //add 11/30
                var userTemp = _userRepository.GetAll().ToList();
                var inspectionStandardDesc = await _inspectionStandardDescRepository.FirstOrDefaultAsync(d => d.Id == input.Id);
                if (inspectionStandardDesc != null)
                {
                    if (inspectionStandardDesc.HandlerId == null || inspectionStandardDesc.HandlerId == userId)
                    {
                        inspectionStandardDesc.State = (States)input.State;

                        var user = _userRepository.FirstOrDefault(s => s.Id == userId);
                        var username = user.Surname + user.Name;
                        if (inspectionStandardDesc.State == States.处理中)
                        {
                            inspectionStandardDesc.HandlerId = input.UserId;
                            _iOperationHistoryAppService.InsertOperationLog(inspectionStandardDesc.Id, 9, 28, username + "开始处理异常");
                        }
                        if (inspectionStandardDesc.State == States.待确认)
                        {
                            inspectionStandardDesc.HandlerId = input.HandlerId;
                            inspectionStandardDesc.CompleteTime = input.HandleTime;
                            inspectionStandardDesc.CauseAnalysis = input.CauseAnalysis;
                            inspectionStandardDesc.TreatmentMeasures = input.TreatmentMeasures;
                            inspectionStandardDesc.CostTime = input.CostTime;
                            _iOperationHistoryAppService.InsertOperationLog(inspectionStandardDesc.Id, 9, 29, username + "处理了异常<br>预计完成时间" + input.HandleTime + "处理方案：" + input.TreatmentMeasures);
                        }
                        await _inspectionStandardDescRepository.UpdateAsync(inspectionStandardDesc);
                    }
                    else
                    {
                        resultMessage.code = 1;
                        resultMessage.Message = "您不是指定的处理人/其他人正在处理该异常";
                        return resultMessage;
                        //+userTemp.FirstOrDefault(d => d.Id == inspectionStandardDesc.HandlerId).Name +
                        //throw new UserFriendlyException("您不是指定的处理人/其他人正在处理该异常");
                    }
                }
                else
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "没有找到对应的数据";
                    return resultMessage;
                    //throw new UserFriendlyException("没有找到对应的数据");
                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
        /// <summary>
        /// 异常管理页面查询(只有处理人能查看)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<InspectionStandardDescOutDto>> GetInspectionStandardDescList(GetInspectionStandardDescInput input)
        {
            var userRoleList = _userRoleRepository.GetAll().ToList();
            var userList = _userRepository.GetAll().ToList();
            var organizationUnitList = _organizationUnitRepository.GetAll().ToList();
            var rolesList = _roleManager.Roles.ToList();
            var user = from ii in _inspectionItemInfoRepository.GetAll()
                       join ur in userRoleList
                       on ii.RolesId equals ur.RoleId
                       where ur.UserId == input.UserId
                       select ii;
            var inspectionStardardDesc = from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll()
                                         join iu in user
                                         on inspectionStandardDesc.InspectionItemInfoId equals iu.Id
                                         join inspectionTypeDesc in _inspectionTypeDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionTypeDescId equals inspectionTypeDesc.Id
                                         join inspectionItemInfo in _inspectionItemInfoRepository.GetAll()
                                         on inspectionStandardDesc.InspectionItemInfoId equals inspectionItemInfo.Id
                                         join inspectionSeverityDesc in _inspectionSeverityDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionSeverityDescId equals inspectionSeverityDesc.Id
                                         join users in userList on inspectionStandardDesc.CreatorUserId equals users.Id
                                         join role in rolesList
                                         on inspectionItemInfo.RolesId equals role.Id into roled
                                         from rolet in roled.DefaultIfEmpty()
                                         join organizationUnit in organizationUnitList
                                         on inspectionItemInfo.OrganizationUnitsId equals organizationUnit.Id into organizationUnitd
                                         from organizationUnitt in organizationUnitd.DefaultIfEmpty()
                                         join userh in userList
                                         on inspectionStandardDesc.HandlerId equals userh.Id into userhd
                                         from userht in userhd.DefaultIfEmpty()
                                         join userc in userList
                                         on inspectionStandardDesc.ConfirmerId equals userc.Id into usercd
                                         from userct in usercd.DefaultIfEmpty()
                                         select new InspectionStandardDescOutDto
                                         {
                                             Id = inspectionStandardDesc.Id,
                                             Code = inspectionStandardDesc.Code,
                                             TaskCode = inspectionStandardDesc.TaskCode,
                                             TaskCodeId = inspectionStandardDesc.TaskCodeId,
                                             InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                             InspectionTypeDesc = inspectionTypeDesc.TypeName,
                                             InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                             InspectionItemInfo = inspectionItemInfo.ItemName,
                                             InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                             InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                             InspectionSeverityDesc = inspectionSeverityDesc.SeverityName,
                                             State = (int)inspectionStandardDesc.State,
                                             Submitter = users.Surname + users.Name,
                                             CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                             CreationTime = inspectionStandardDesc.CreationTime,
                                             Roles = rolet.DisplayName,
                                             RolesId = inspectionItemInfo.RolesId,
                                             OrganizationUnitsId = inspectionItemInfo.OrganizationUnitsId,
                                             OrganizationUnits = organizationUnitt.DisplayName,
                                             HandlerId = inspectionStandardDesc.HandlerId,
                                             Handler = userht.Surname + userht.Name,
                                             CompleteTime = inspectionStandardDesc.CompleteTime,
                                             CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                             TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                             RequestCompleteTime = inspectionStandardDesc.RequestCompleteTime,
                                             CostTime = inspectionStandardDesc.CostTime,
                                             ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                             Confirmer = userct.Surname + userct.Name,
                                             ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                             ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest
                                         };

            if (!string.IsNullOrEmpty(input.TaskCode))
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.TaskCode.Contains(input.TaskCode));
            }
            if (input.InspectionTypeDescId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionTypeDescId == input.InspectionTypeDescId);
            }
            if (input.InspectionItemInfoId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionItemInfoId == input.InspectionItemInfoId);
            }
            if (input.InspectionSeverityDescId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionSeverityDescId == input.InspectionSeverityDescId);
            }
            if (input.SubmitterId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.CreatorUserId == input.SubmitterId);
            }
            if (input.HandlerId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.HandlerId == input.HandlerId);
            }
            var count = inspectionStardardDesc.Count();
            inspectionStardardDesc = inspectionStardardDesc.OrderByDescending(e => e.CreationTime).PageBy(input);
            var result = ObjectMapper.Map<List<InspectionStandardDescOutDto>>(inspectionStardardDesc);
            result.ForEach(d =>
            {
                if (d.HandlerId != null && d.HandlerId == 0)
                {
                    d.Handler = _userRepository.FirstOrDefault(s => s.Id == d.HandlerId).Surname + _userRepository.FirstOrDefault(s => s.Id == d.HandlerId).Name;
                    if (input.UserId == d.HandlerId)
                    {
                        d.Flag = 1;
                    }
                    else
                    {
                        d.Flag = 0;
                    }
                }
                else
                {
                    d.Flag = 1;
                }
                //查询上传图片信息
                string url = ConfigHelper.GetAppSetting("App", "GetAppUrl") + "/Inspection/";
                //var flieList = _uploadPictureRepository.GetAll().Where(s => s.BusinessId == d.Id);
                var flieList = (from up in _uploadPictureRepository.GetAll().Where(s => s.BusinessId == d.Id)
                                select new UploadPicture
                                {
                                    Id = up.Id,
                                    CreationTime = up.CreationTime,
                                    CreatorUserId = up.CreatorUserId,
                                    FileName = up.FileName,
                                    FileUrl = url + up.FileName,
                                    Size = up.Size
                                });

                if (flieList != null)
                {
                    var flieResult = ObjectMapper.Map<List<InspectionFileUploadDto>>(flieList.ToList());
                    d.InspectionFileUploadDto = flieResult.ToList();
                }
            });
            return new PagedResultDto<InspectionStandardDescOutDto>(count, result);
        }
        /// <summary>
        /// 处理异常导出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> GetInspectionStandardHandleToExcel(GetInspectionStandardDescInput input)
        {
            var userRoleList = _userRoleRepository.GetAll().ToList();
            var userList = _userRepository.GetAll().ToList();
            var organizationUnitList = _organizationUnitRepository.GetAll().ToList();
            var rolesList = _roleManager.Roles.ToList();
            var user = from ii in _inspectionItemInfoRepository.GetAll()
                       join ur in userRoleList
                       on ii.RolesId equals ur.RoleId
                       where ur.UserId == input.UserId
                       select ii;
            var inspectionStardardDesc = from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll()
                                         join iu in user
                                         on inspectionStandardDesc.InspectionItemInfoId equals iu.Id
                                         join inspectionTypeDesc in _inspectionTypeDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionTypeDescId equals inspectionTypeDesc.Id
                                         join inspectionItemInfo in _inspectionItemInfoRepository.GetAll()
                                         on inspectionStandardDesc.InspectionItemInfoId equals inspectionItemInfo.Id
                                         join inspectionSeverityDesc in _inspectionSeverityDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionSeverityDescId equals inspectionSeverityDesc.Id
                                         join users in userList on inspectionStandardDesc.CreatorUserId equals users.Id
                                         join role in rolesList
                                         on inspectionItemInfo.RolesId equals role.Id into roled
                                         from rolet in roled.DefaultIfEmpty()
                                         join organizationUnit in organizationUnitList
                                         on inspectionItemInfo.OrganizationUnitsId equals organizationUnit.Id into organizationUnitd
                                         from organizationUnitt in organizationUnitd.DefaultIfEmpty()
                                         join userh in userList
                                         on inspectionStandardDesc.HandlerId equals userh.Id into userhd
                                         from userht in userhd.DefaultIfEmpty()
                                         join userc in userList
                                         on inspectionStandardDesc.ConfirmerId equals userc.Id into usercd
                                         from userct in usercd.DefaultIfEmpty()
                                         select new InspectionStandardDescOutDto
                                         {
                                             Id = inspectionStandardDesc.Id,
                                             Code = inspectionStandardDesc.Code,
                                             TaskCode = inspectionStandardDesc.TaskCode,
                                             TaskCodeId = inspectionStandardDesc.TaskCodeId,
                                             InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                             InspectionTypeDesc = inspectionTypeDesc.TypeName,
                                             InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                             InspectionItemInfo = inspectionItemInfo.ItemName,
                                             InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                             InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                             InspectionSeverityDesc = inspectionSeverityDesc.SeverityName,
                                             State = (int)inspectionStandardDesc.State,
                                             Submitter = users.Surname + users.Name,
                                             CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                             CreationTime = inspectionStandardDesc.CreationTime,
                                             Roles = rolet.DisplayName,
                                             RolesId = inspectionItemInfo.RolesId,
                                             OrganizationUnitsId = inspectionItemInfo.OrganizationUnitsId,
                                             OrganizationUnits = organizationUnitt.DisplayName,
                                             HandlerId = inspectionStandardDesc.HandlerId,
                                             Handler = userht.Surname + userht.Name,
                                             CompleteTime = inspectionStandardDesc.CompleteTime,
                                             CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                             TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                             RequestCompleteTime = inspectionStandardDesc.RequestCompleteTime,
                                             CostTime = inspectionStandardDesc.CostTime,
                                             ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                             Confirmer = userct.Surname + userct.Name,
                                             ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                             ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest
                                         };
            if (!string.IsNullOrEmpty(input.TaskCode))
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.TaskCode.Contains(input.TaskCode));
            }
            if (input.InspectionTypeDescId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionTypeDescId == input.InspectionTypeDescId);
            }
            if (input.InspectionItemInfoId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionItemInfoId == input.InspectionItemInfoId);
            }
            if (input.InspectionSeverityDescId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.InspectionSeverityDescId == input.InspectionSeverityDescId);
            }
            if (input.SubmitterId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.CreatorUserId == input.SubmitterId);
            }
            if (input.HandlerId != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(d => d.HandlerId == input.HandlerId);
            }
            inspectionStardardDesc = inspectionStardardDesc.OrderByDescending(e => e.CreationTime).PageBy(input);
            var result = ObjectMapper.Map<List<InspectionStandardDescOutDto>>(inspectionStardardDesc);
            InspectionExportAppService service = new InspectionExportAppService(_tempFileCacheManager);
            return service.ExportToFile(result);
        }
    }
}
